home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 8
/
Aminet 8 (1995)(GTI - Schatztruhe)[!][Oct 1995].iso
/
Aminet
/
comm
/
tcp
/
PutMailSRC.lha
/
PutMail.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-06-08
|
19KB
|
855 lines
/*
* SMTP Send Mail Utility.
*/
#define __Program__ "PutMail"
#define __Version__ "1.23"
#include <Defaults.h>
#include <SMTP.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/intuition.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/dir.h>
#include <dos/stdio.h>
#include <dos/dosextens.h>
#include <exec/memory.h>
#define AMITCP_NEW_NAMES
#define _OPTINLINE
#include <LocalInclude:AmiTCP/errno.h>
#include <netdb.h>
BPTR fhIn = NULL, fhOut = NULL;
struct Remember *MemList = NULL;
BPTR Console = NULL, MyConsole = NULL;
#define OPT_TEMPLATE "MAIL=MAILFILE/A,TO=RECIPIENT/K/M,SUB=SUBJECT/K,HOME/K,REPLYTO/K,SMTPHOST/K,NOHEAD/S,NOADDR/S,NOSIG/S,VERBOSE/S"
#define OPT_MAIL 0
#define OPT_TO 1
#define OPT_SUB 2
#define OPT_HOME 3
#define OPT_REPLYTO 4
#define OPT_SMTPHOST 5
#define OPT_NOHEAD 6
#define OPT_NOADDR 7
#define OPT_NOSIG 8
#define OPT_VERBOSE 9
#define OPT_COUNT 10
struct RDArgs *Args;
LONG Options[OPT_COUNT];
STRPTR Mail; // Mail file name.
STRPTR *To; // TO Address.
STRPTR Subject; // Subject text.
STRPTR HomeDir; // Home directory.
STRPTR ReplyTo; // E-Mail address to send replies to.
STRPTR SMTPHost; // SMTP Mail Host.
BOOL NoHead;
BOOL NoAddr;
BOOL NoSig;
BOOL Verbose;
STRPTR Domain;
#define USERID_LEN 16
char UserID[USERID_LEN];
#define USERNAME_LEN 64
char UserName[USERNAME_LEN];
#define HOSTNAME_LEN 256
char HostName[HOSTNAME_LEN];
char MailTemp[MAXNAMLEN + 1];
#define CMDBUF_SIZE 512
#define DATBUF_SIZE 1024
int hSocket = SMTP_NO_SOCKET;
struct sockaddr_in INetSocketAddr;
void __regargs Abort(STRPTR ErrorMsg, BOOL ErrorCR, int ErrorRC, LONG Error2);
void __regargs Message(STRPTR Msg, BOOL CR)
{
if (!Console)
{
if (Console = Output())
MyConsole = NULL;
else
Console = MyConsole = Open(STDIO, MODE_READWRITE);
Write(Console, "\n", 1);
Message(Version, TRUE);
Message("Written by Martin V Lanza.\n", TRUE);
}
if (Msg) Write(Console, Msg, strlen(Msg));
if (CR) Write(Console, "\n", 1);
return;
}
void __regargs VerboseMsg(STRPTR Func, STRPTR Name, STRPTR Value)
{
static BOOL DoLF;
static char Msg[DATBUF_SIZE * 2];
if (!Verbose) return;
sprintf(Msg, "%-16s ", Func);
if (Name) strcat(Msg, Name);
if (Value) strcat(Msg, Value);
if (Msg[strlen(Msg)-1] == '\n')
DoLF = FALSE;
else
DoLF = TRUE;
Message(Msg, DoLF);
return;
}
BOOL __regargs RecvDat(STRPTR DatBuf, int *DatLen)
{
static char Func[] = "RecvDat";
errno = 0;
if (hSocket == SMTP_NO_SOCKET) return(FALSE);
*DatLen = Recv(hSocket, DatBuf, DATBUF_SIZE - 1, 0);
if (*DatLen) DatBuf[*DatLen] = '\0'; else DatBuf[0] = '\0';
VerboseMsg(Func, "Recv() ", DatBuf);
return(TRUE);
}
BOOL __regargs SendDat(STRPTR SendData)
{
static char Func[] = "SendDat";
static char StrBuf[DATBUF_SIZE];
if (hSocket == SMTP_NO_SOCKET) return(FALSE);
if (!SendData) return(TRUE);
// Conform to RFC821.
// This prevents premature message termination by user text.
*StrBuf = '\0';
if (SendData[0] == '.')
if (SendData[1] == '\r')
if (SendData[2] == '\n')
{
StrBuf[0] = '.';
StrBuf[1] = '\0';
}
strcat(StrBuf, SendData);
VerboseMsg(Func, "Send() ", StrBuf);
if (Send(hSocket, StrBuf, strlen(StrBuf), 0) != -1) return(TRUE);
Abort("Socket message send failure.", TRUE, RETURN_FAIL, Errno());
return(FALSE);
}
void __regargs SendCmd(STRPTR CmdText, STRPTR ParmText)
{
static int StrLen;
static char StrBuf[DATBUF_SIZE];
if (hSocket == SMTP_NO_SOCKET) return;
if (!CmdText || !*CmdText)
*StrBuf = '\0';
else
if (!ParmText || !*ParmText)
sprintf(StrBuf, "%s\r\n", CmdText);
else
sprintf(StrBuf, "%s %s\r\n", CmdText, ParmText);
if (!SendDat(StrBuf)) return;
if (!RecvDat(StrBuf, &StrLen)) return;
switch (atoi(StrBuf))
{
case SMTP_STATUS_REPLY : break;
case SMTP_HELP_MESSAGE : break;
case SMTP_SERVICE_READY: break;
case SMTP_SERVICE_CLOSE: break;
case SMTP_OK : break;
case SMTP_OK_FORWARD : break;
case SMTP_SEND_MAIL : break;
default:
{
char ErrorMsg[256];
sprintf(ErrorMsg, "Bad %s command response: %s", CmdText, StrBuf);
Abort(ErrorMsg, TRUE, RETURN_FAIL, ERROR_BAD_NUMBER);
}
}
// Extended responce may not fit in the buffer :-(
// Keep reading untill we get it all.
if (StrBuf[3] == '-')
while (StrBuf[StrLen - 1] != '\n')
if (!RecvDat(StrBuf, &StrLen)) break;
return;
}
void __regargs SocketDisconnect(void)
{
char Func[] = "SocketDisconnect";
if (hSocket != SMTP_NO_SOCKET)
{
SendCmd("QUIT", NULL);
Shutdown(hSocket, 2);
CloseSocket(hSocket);
hSocket = SMTP_NO_SOCKET;
VerboseMsg(Func, "Disconnected from SMTP Host ", SMTPHost);
}
return;
}
void __regargs CleanUp(void)
{
char Func[] = "CleanUp";
VerboseMsg(Func, "Cleanup in progress.", NULL);
if (fhIn) Close(fhIn);
if (fhOut) Close(fhOut);
if (Args) FreeArgs(Args);
if (MemList) FreeRemember(&MemList, TRUE);
if (MyConsole)
{
Message("\nPress RETURN to terminate program: ", FALSE);
FGetC(MyConsole);
Close(MyConsole);
}
return;
}
void __regargs Abort(STRPTR ErrorMsg, BOOL ErrorCR, int ErrorRC, LONG Error2)
{
static BOOL Aborting;
if (Aborting) return;
Aborting = TRUE;
if (ErrorMsg)
{
Message(__Program__ ": ", FALSE);
Message(ErrorMsg, ErrorCR);
}
SendCmd("RSET", NULL);
SocketDisconnect();
CleanUp();
if (Error2) ((struct Process *) FindTask(NULL))->pr_Result2 = Error2;
exit(ErrorRC);
}
void __regargs SocketConnect(void)
{
struct hostent *HostAddr;
char Func[] = "SocketConnect";
HostAddr = GetHostByName(SMTPHost);
if (!HostAddr)
{
VerboseMsg(Func, "GetHostByName() ", SMTPHost);
if (h_errno == TRY_AGAIN)
Abort("Unable to locate the SMTP Host, try again later.", TRUE, RETURN_FAIL, h_errno);
else
Abort("The SMTP Host is invalid.", TRUE, RETURN_FAIL, h_errno);
}
INetSocketAddr.sin_len = sizeof(INetSocketAddr);
INetSocketAddr.sin_family = AF_INET;
INetSocketAddr.sin_port = 25; // SMTP
INetSocketAddr.sin_addr.s_addr = 0;
memcpy(&INetSocketAddr.sin_addr, HostAddr->h_addr, HostAddr->h_length);
hSocket = Socket(HostAddr->h_addrtype, SOCK_STREAM, 0);
if (hSocket == SMTP_NO_SOCKET)
{
VerboseMsg(Func, "Socket() Failed!", NULL);
Abort("Socket allocation failed.", TRUE, RETURN_FAIL, Errno());
}
if (Connect(hSocket, (struct sockaddr *) &INetSocketAddr, sizeof(INetSocketAddr)) == -1)
{
VerboseMsg(Func, "Connect() Failed!", NULL);
Abort("Socket connection failed.", TRUE, RETURN_FAIL, Errno());
}
VerboseMsg(Func, "Connected to SMTP Host ", SMTPHost);
SendCmd(NULL, NULL); // Check for the Welcome... message.
SendCmd("HELO", HostName); // Say HELLO, Receive HELLO.
return;
}
BOOL __regargs GetEnvVar(STRPTR Name, STRPTR Buffer, long Len)
{
static int BufLen, EnvLen;
BufLen = GetVar(Name, Buffer, Len - 1, GVF_GLOBAL_ONLY);
EnvLen = IoErr();
SetIoErr(NULL);
if (BufLen <= NULL) return(FALSE);
if (BufLen != EnvLen) return(FALSE);
return(TRUE);
}
BOOL __regargs GetEMailAddr(void)
{
int Len;
BPTR fhFile;
char strName[MAXNAMLEN + 1];
char Func[] = "GetEMailAddr";
strcpy(strName, HomeDir);
AddPart(strName, ".EMailAddr", MAXNAMLEN);
if (!(fhFile = Open(strName, MODE_OLDFILE)))
{
VerboseMsg(Func, strName, " could not be opened.");
return(FALSE);
}
VerboseMsg(Func, strName, " successfully opened.");
FGets(fhFile, ReplyTo, USERID_LEN + HOSTNAME_LEN);
if (IoErr())
{
VerboseMsg(Func, "Read failure on ", strName);
Close(fhFile);
return(FALSE);
}
Close(fhFile);
Len = strlen(ReplyTo);
if (!Len) return(FALSE);
while (--Len)
{
if (ReplyTo[Len] != ' ')
if (ReplyTo[Len] != '\r')
if (ReplyTo[Len] != '\n')
break;
ReplyTo[Len] = '\0';
}
return(TRUE);
}
void __regargs InitProg(void)
{
struct passwd *UserList;
char Func[] = "InitProg";
struct DateStamp TheDateStamp;
memset(Options, NULL, sizeof(LONG) * OPT_COUNT);
Args = ReadArgs(OPT_TEMPLATE, Options, NULL);
if (!Args)
{
PrintFault(IoErr(), NULL);
Abort("Argument Template is " OPT_TEMPLATE, TRUE, RETURN_FAIL, ERROR_BAD_TEMPLATE);
}
Mail = (STRPTR) Options[OPT_MAIL];
To = (STRPTR *) Options[OPT_TO];
Subject = (STRPTR) Options[OPT_SUB];
HomeDir = (STRPTR) Options[OPT_HOME];
ReplyTo = (STRPTR) Options[OPT_REPLYTO];
SMTPHost = (STRPTR) Options[OPT_SMTPHOST];
NoHead = Options[OPT_NOHEAD];
NoAddr = Options[OPT_NOADDR];
NoSig = Options[OPT_NOSIG];
Verbose = Options[OPT_VERBOSE];
DateStamp(&TheDateStamp);
sprintf(MailTemp, "T:PutMail.%ld@%ld", FindTask(NULL), TheDateStamp.ds_Minute);
if (!GetEnvVar("USER", UserID, USERID_LEN))
Abort("ENV variable 'USER' not found.", TRUE, RETURN_FAIL, NULL);
if ((UserList = getpwnam(UserID)))
strcpy(UserName, UserList->pw_gecos);
else
*UserName = '\0';
if (!HomeDir)
{
HomeDir = AllocRemember(&MemList, MAXNAMLEN + 1, MEMF_ANY | MEMF_CLEAR);
if (!HomeDir) Abort("Not enough free memory.", TRUE, RETURN_FAIL, ERROR_NO_FREE_STORE);
if (!GetEnvVar("HOME", HomeDir, MAXNAMLEN))
Abort("'HOME' not found.", TRUE, RETURN_FAIL, NULL);
}
if (!GetEnvVar("HOSTNAME", HostName, HOSTNAME_LEN))
Abort("ENV variable 'HOSTNAME' not found.", TRUE, RETURN_FAIL, NULL);
Domain = HostName;
while (*Domain && *Domain != '.') Domain++;
if (*Domain) Domain++;
if (!SMTPHost)
{
SMTPHost = AllocRemember(&MemList, HOSTNAME_LEN, MEMF_ANY | MEMF_CLEAR);
if (!SMTPHost) Abort("Not enough free memory.", TRUE, RETURN_FAIL, ERROR_NO_FREE_STORE);
if (!GetEnvVar("SMTPHOST", SMTPHost, HOSTNAME_LEN))
{
struct hostent *HostAddr;
if (HostAddr = GetHostByName("SMTPHOST"))
strcpy(SMTPHost, HostAddr->h_name);
else
{
strcpy(SMTPHost, Domain);
VerboseMsg(Func, "SMTPHost name not provided, assumed ", SMTPHost);
}
}
}
if (!ReplyTo)
{
ReplyTo = AllocRemember(&MemList, USERID_LEN + HOSTNAME_LEN, MEMF_ANY | MEMF_CLEAR);
if (!ReplyTo) Abort("Not enough free memory.", TRUE, RETURN_FAIL, ERROR_NO_FREE_STORE);
if (!GetEnvVar("EMAILADDR", ReplyTo, USERID_LEN + HOSTNAME_LEN))
if (!GetEMailAddr())
{
sprintf(ReplyTo, "%s@%s", UserID, SMTPHost);
VerboseMsg(Func, "ReplyTo & EMAILADDR not provided, assumed ", ReplyTo);
}
}
if (Verbose)
{
VerboseMsg(Func, "MailFile=", Mail);
if (Subject) VerboseMsg(Func, "Subject=", Subject);
VerboseMsg(Func, "Home=", HomeDir);
VerboseMsg(Func, "ReplyTo=", ReplyTo);
VerboseMsg(Func, "SMTPHost=", SMTPHost);
NoHead ? VerboseMsg(Func, "NoHead=", "TRUE") : VerboseMsg(Func, "NoHead=", "FALSE");
NoAddr ? VerboseMsg(Func, "NoAddr=", "TRUE") : VerboseMsg(Func, "NoAddr=", "FALSE");
NoSig ? VerboseMsg(Func, "NoSig=", "TRUE") : VerboseMsg(Func, "NoSig=", "FALSE");
Verbose ? VerboseMsg(Func, "Verbose=", "TRUE") : VerboseMsg(Func, "Verbose=", "FALSE");
}
return;
}
void __regargs CopyFile(int NoBlankLines, STRPTR ErrText)
{
static char StrBuf[DATBUF_SIZE];
while(FGets(fhIn, StrBuf, DATBUF_SIZE))
{
int register i;
i = strlen(StrBuf) - 1;
//Strip CR & LF to avoid Amiga/IBM differences.
if (i >= 0 && StrBuf[i] == '\n') StrBuf[i--] = '\0';
if (i >= 0 && StrBuf[i] == '\r') StrBuf[i--] = '\0';
while (i >= 0 && StrBuf[i] == ' ') i--;
if (i < 0 && NoBlankLines) continue;
//Put standard CR LF on end of line.
StrBuf[++i] = '\r';
StrBuf[++i] = '\n';
StrBuf[++i] = '\0';
if (FPuts(fhOut, StrBuf))
if (IoErr()) Abort("Write Error on temporary mail file.", TRUE, RETURN_FAIL, NULL);
}
if (IoErr()) Abort(ErrText, TRUE, RETURN_FAIL, NULL);
Close(fhIn);
fhIn = NULL;
return;
}
BPTR __regargs OpenFile(STRPTR Path, STRPTR Name, LONG Mode)
{
static BPTR fhFile;
static char strMode[33];
static char strName[MAXNAMLEN + 1];
static char Func[] = "OpenFile";
switch (Mode)
{
case MODE_OLDFILE:
strcpy(strMode, " opened for Input."); break;
case MODE_NEWFILE:
strcpy(strMode, " opened for Output."); break;
case MODE_READWRITE:
strcpy(strMode, " opened for Input & Output."); break;
}
strcpy(strName, Path);
AddPart(strName, Name, MAXNAMLEN);
fhFile = Open(strName, Mode);
if (fhFile)
{
VerboseMsg(Func, strName, strMode);
if (!SetVBuf(fhFile, NULL, BUF_FULL, 4096))
VerboseMsg(Func, strName, " will be buffered.");
}
else
VerboseMsg(Func, "Unable to open ", strName);
return(fhFile);
}
void __regargs CreateMail(void)
{
char Advert[DATBUF_SIZE];
char StrBuf[DATBUF_SIZE];
char StrDay[LEN_DATSTRING];
char StrDate[LEN_DATSTRING];
char StrTime[LEN_DATSTRING];
struct DateTime TheDateTime;
// Advertisement :-)
sprintf(Advert, "X-SMTP-Client: Amiga %s %s by Martin Lanza.\r\n", __Program__, __Version__);
if (!(fhOut = OpenFile("", MailTemp, MODE_NEWFILE)))
Abort("Unable to create temporary mail file.", TRUE, RETURN_FAIL, IoErr());
if (NoHead && NoAddr) FPuts(fhOut, Advert);
if (!NoHead)
{
if (fhIn = OpenFile(HomeDir, ".header", MODE_OLDFILE))
CopyFile(TRUE, "Error reading '.header' file.");
if (NoAddr) FPuts(fhOut, Advert);
}
if (!NoAddr)
{
// From:
if (*UserName)
sprintf(StrBuf, "From: %s@%s (%s)\r\n", UserID, HostName, UserName);
else
sprintf(StrBuf, "From: %s@%s\r\n", UserID, HostName);
FPuts(fhOut, StrBuf);
// X-SMTP-Client:
FPuts(fhOut, Advert);
// Date:
DateStamp(&TheDateTime.dat_Stamp);
TheDateTime.dat_Format = FORMAT_DOS;
TheDateTime.dat_Flags = NULL;
TheDateTime.dat_StrDay = StrDay;
TheDateTime.dat_StrDate = StrDate;
TheDateTime.dat_StrTime = StrTime;
DateToStr(&TheDateTime);
StrDate[2] = ' '; StrDate[6] = ' ';
sprintf(StrBuf, "Date: %3.3s, %s %s\r\n", StrDay, StrDate, StrTime);
FPuts(fhOut, StrBuf);
// Reply-To:
if (ReplyTo)
{
sprintf(StrBuf, "Reply-To: %s\r\n", ReplyTo);
FPuts(fhOut, StrBuf);
}
// To:
if (To)
{
int i;
char Desc[] = "To:";
for (i=0; To[i]; i++)
{
sprintf(StrBuf, "%3.3s %s \r\n", Desc, To[i]);
if (To[i+1]) StrBuf[strlen(StrBuf) - 3] = ',';
strcpy(Desc, " ");
FPuts(fhOut, StrBuf);
}
}
// Subject:
if (Subject)
{
sprintf(StrBuf, "Subject: %s\r\n", Subject);
FPuts(fhOut, StrBuf);
}
if (To)
if(To[0])
{
sprintf(StrBuf, "\r\n");
FPuts(fhOut, StrBuf);
}
}
if (Mail)
if (fhIn = OpenFile("", Mail, MODE_OLDFILE))
CopyFile(FALSE, "Error reading Mail file.");
else
Abort("Unable to process Mail input file.", TRUE, RETURN_FAIL, IoErr());
if (!NoSig)
if (fhIn = OpenFile(HomeDir, ".signature", MODE_OLDFILE))
CopyFile(FALSE, "Error reading '.signature' file.");
Close(fhOut);
fhOut = NULL;
return;
}
void __regargs FilteredAppend(STRPTR Srce, STRPTR Dest)
{
int register i=0, j=0;
int max = DATBUF_SIZE * 2;
// Find end of Dest.
while(Dest[j]) j++;
while(Srce[i])
{
// Filter these.
if (Srce[i] != '\t')
if (Srce[i] != '\r')
if (Srce[i] != '\n')
// Copy char.
Dest[j++] = Srce[i];
i++;
if (j >= max)
Abort("'To:' string exceeds buffer size or is illegal.", TRUE, RETURN_FAIL, NULL);
}
Dest[j] = '\0';
return;
}
void __regargs LocateTo(void)
{
int i;
STRPTR ToData;
STRPTR *ToArray;
char Desc[] = "To: ";
char StrBuf[DATBUF_SIZE];
char Func[] = "LocateTo";
if (To)
if (To[0])
return;
ToData = AllocRemember(&MemList, DATBUF_SIZE * 2, MEMF_ANY | MEMF_CLEAR);
if (!ToData) Abort("Not enough free memory.", TRUE, RETURN_FAIL, ERROR_NO_FREE_STORE);
ToArray = AllocRemember(&MemList, sizeof(STRPTR) * 64, MEMF_ANY | MEMF_CLEAR);
if (!ToArray) Abort("Not enough free memory.", TRUE, RETURN_FAIL, ERROR_NO_FREE_STORE);
if (!(fhIn = OpenFile("", MailTemp, MODE_OLDFILE)))
Abort("Unable to open temporary mail file.", TRUE, RETURN_FAIL, IoErr());
VerboseMsg(Func, "Scanning temporary mail file for 'To:'.", NULL);
while(FGets(fhIn, StrBuf, DATBUF_SIZE))
{
if (*StrBuf == '\r')
// This must mean we are past the message header.
Abort("Unable to locate 'To:' address.", TRUE, RETURN_FAIL, NULL);
if (!strnicmp(StrBuf, "To: ", 4)) break;
}
if (IoErr()) Abort("Read Error on temporary mail file.", TRUE, RETURN_FAIL, IoErr());
FilteredAppend(&StrBuf[4], ToData);
while (FGets(fhIn, StrBuf, DATBUF_SIZE))
{
if (StrBuf[0] != ' ' && StrBuf[0] != '\t') break;
FilteredAppend(StrBuf, ToData);
}
if (IoErr()) Abort("Read Error on temporary mail file.", TRUE, RETURN_FAIL, IoErr());
Close(fhIn);
fhIn = NULL;
i=0;
ToArray[i++] = ToData;
while(*ToData && i < 63)
{
if (*ToData == ',')
{
*ToData = '\0';
ToArray[i++] = ToData + 1;
}
ToData++;
}
To = ToArray;
for (i=0; To[i]; i++)
{
// Ignore leading spaces.
while(To[i] && *To[i] == ' ') To[i]++;
VerboseMsg(Func, Desc, To[i]);
strcpy(Desc, " & ");
}
return;
}
void __regargs MailInit(void)
{
int i;
STRPTR ToAddr, RouteAddr[2];
char ToStr[USERID_LEN + HOSTNAME_LEN + 10];
char FromStr[USERID_LEN + HOSTNAME_LEN + 10];
sprintf(FromStr, "FROM:<%s@%s>", UserID, HostName);
SendCmd("MAIL", FromStr);
for (i = 0; To[i]; i++)
{
RouteAddr[0] = strchr(To[i], '<');
RouteAddr[1] = strchr(To[i], '>');
if (RouteAddr[0] && RouteAddr[1])
{
strcpy(ToStr, "To:");
strncat(ToStr, RouteAddr[0], 1 + RouteAddr[1] - RouteAddr[0]);
}
else
{
// Ignore leading spaces.
while(To[i] && *To[i] == ' ') To[i]++;
// Ignore trailing spaces.
ToAddr = To[i] + strlen(To[i]) - 1;
while (*ToAddr == ' ' && ToAddr > To[i])
*(ToAddr--) = '\0';
sprintf(ToStr, "To:<%s>", To[i]);
}
SendCmd("RCPT", ToStr);
}
SendCmd("DATA", NULL);
return;
}
void __regargs MailSend(void)
{
char strBuf[DATBUF_SIZE];
if (!(fhIn = OpenFile("", MailTemp, MODE_OLDFILE)))
Abort("Unable to open temporary mail file.", TRUE, RETURN_FAIL, IoErr());
while(FGets(fhIn, strBuf, DATBUF_SIZE)) SendDat(strBuf);
if (IoErr()) Abort("Read Error on temporary mail file.", TRUE, RETURN_FAIL, IoErr());
Close(fhIn);
fhIn = NULL;
return;
}
void __regargs MailEnd(void)
{
char Func[] = "MailEnd";
SendCmd("\r\n.", NULL);
VerboseMsg(Func, "Mail successfully sent.", NULL);
return;
}
int __regargs main(int argc, char **argv)
{
if (!argc) exit(RETURN_FAIL);
InitProg();
CreateMail();
LocateTo();
SocketConnect();
MailInit();
MailSend();
MailEnd();
SocketDisconnect();
CleanUp();
DeleteFile(MailTemp);
return(RETURN_OK);
}